package cz.data.auth.controller;

import com.alibaba.nacos.api.exception.NacosException;
import com.nimbusds.jose.KeySourceException;
import cz.data.auth.service.SecurityService;
import cz.data.common.annotation.DataInner;
import cz.data.common.base.BaseResponse;
import cz.data.common.base.SimpleDataResponse;
import cz.data.common.core.AuthUser;
import cz.data.common.core.DataConstant;
import cz.data.common.core.DataUser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class SecurityController {

    @Resource
    SecurityService securityService;

    @GetMapping(value = "/oauth/userinfo")
    public SimpleDataResponse<DataUser> userinfo() {
        return new SimpleDataResponse<>(securityService.userinfo());
    }

    @DataInner
    @GetMapping(value = "/oauth/authorize/userinfo")
    public SimpleDataResponse<AuthUser> authorizeUserinfo(@RequestHeader(HttpHeaders.AUTHORIZATION) String tokenValue) {
        return new SimpleDataResponse<>(securityService.authUser(tokenValue));
    }

    @GetMapping("/oauth/logout")
    public BaseResponse logout(@RequestHeader(value = DataConstant.Token.TOKEN_JTI_HEADER, required = false) String jti) {
        if (StringUtils.isBlank(jti)) {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication instanceof JwtAuthenticationToken) {
                JwtAuthenticationToken jwtAuthenticationToken = (JwtAuthenticationToken) authentication;
                jti = jwtAuthenticationToken.getToken().getClaim("jti");
            }
        }
        return BaseResponse.withBoolean(securityService.logout(jti));
    }

    @DataInner(DataInner.Access.permitAll)
    @GetMapping(value = "/oauth/jwks", produces = MediaType.APPLICATION_JSON_VALUE)
    public String jwkSource() throws KeySourceException {
        return securityService.jwkSource();
    }

    @DataInner
    @GetMapping("/oauth/nacos")
    public BaseResponse nacosServiceAuth(@RequestHeader(DataConstant.Token.SERVICE_HEADER) String token) throws NacosException {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Object principal = authentication.getPrincipal();
        return BaseResponse.withBoolean(token.equals(principal)).setMessage("认证完成");
    }

}
